Scala 之 JavaConverters 与 JavaConversions

在实际使用中经常遇见Scala <=> Java之间的转换。例如要调用某个第三方包的方法需要一个Java的Map,那么可能用到Scala提供的JavaConverters或JavaConversions工具包
案例:

//待转换的Map
scala> val m = Map(1->2)
m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)

JavaConversions示例:

import collection.JavaConversions._
scala> val conversionsMap = mapAsJavaMap(m).asInstanceOf[java.util.Map[Int, Int]]
conversionsMap: java.util.Map[Int,Int] = {1=2}

JavaConversters示例:

import scala.collection.JavaConverters._
scala> val convertersMap = m.asJava
convertersMap: java.util.Map[Int,Int] = {1=2}

俩者都转换成功,看似一模一样的效果,为什么共同存在?

scala> conversionsMap.put(3,4)
java.lang.UnsupportedOperationException
  at java.util.AbstractMap.put(AbstractMap.java:203)
  ... 33 elided      

  scala> convertersMap.put(3,4)
  java.lang.UnsupportedOperationException
  at java.util.AbstractMap.put(AbstractMap.java:203)
  ... 33 elided 

转换成功后的Map竟然是不可修改的,这好像不符合我的需求,猜测是因为m是immutable类型的原因,那么继续:

//先转换成mutable
val m2 = collection.mutable.Map(m.toSeq: _*)
scala> m2.+(3->4)
res4: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
  //好,现在m2可以修改了

  scala> val conversionsMap = mapAsJavaMap(m2).asInstanceOf[java.util.Map[Int, Int]]
conversionsMap: java.util.Map[Int,Int] = {1=2}
scala> conversionsMap.put(3,4)
java.lang.UnsupportedOperationException
  at java.util.AbstractMap.put(AbstractMap.java:203)
  ... 33 elided
  //conversionsMap依旧不能修改,囧

scala> val convertersMap = m2.asJava
convertersMap: java.util.Map[Int,Int] = {1=2}
scala> convertersMap.put(3,4)
res5: Int = 0
scala> convertersMap
res6: java.util.Map[Int,Int] = {1=2, 3=4}
//convertersMap 可以修改

那么JavaConversions需要转换出可修改的Map该如何操作,搜索一番得到答案,JavaConversions提供的是Java集合之间的隐式转换,如果想让JavaConversions产出可变的Map应该如下操作:

//JavaConversions直接隐式的转换了
val conversionsMap2: java.util.Map[Int, Int] = m2
scala> conversionsMap2.put(3,4)
res7: Int = 0
scala> conversionsMap2
res8: java.util.Map[Int,Int] = {1=2, 3=4}

JavaConversions出现在V2.8版本,JavaConverters出现于V2.8.1,相比JavaConversions更新,并且显示的转换更易于理解,推荐使用JavaConverters